﻿using Luminescence.Xiph;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System;

namespace XiphTestProject
{
   /// <summary>
   ///This is a test class for OggTaggerTest and is intended to contain all OggTaggerTest Unit Tests
   ///</summary>
   [TestClass()]
   public class OggSpeexTaggerTest
   {
      private TestContext testContextInstance;
      private static string filename = @"E:\Home\Important\Development\Projects\Luminescence.Xiph\Sources\Samples\speex.spx";
      OggTagger target = null;

      public OggSpeexTaggerTest()
      {
         target = new OggTagger(filename);
      }

      /// <summary>
      ///Gets or sets the test context which provides information about and functionality for the current test run.
      ///</summary>
      public TestContext TestContext
      {
         get
         {
            return testContextInstance;
         }
         set
         {
            testContextInstance = value;
         }
      }

      #region Additional test attributes

      // 
      //You can use the following additional attributes as you write your tests:
      //
      //Use ClassInitialize to run code before running the first test in the class
      [ClassInitialize()]
      public static void MyClassInitialize(TestContext testContext)
      {
         OggTagger flac = new OggTagger(filename);
         flac.ClearTags();
         flac.SaveMetadata();
         flac = null;
      }
      //
      //Use ClassCleanup to run code after all tests in a class have run
      //[ClassCleanup()]
      //public static void MyClassCleanup()
      //{
      //}
      //
      //Use TestInitialize to run code before running each test
      //[TestInitialize()]
      //public void MyTestInitialize()
      //{
      //}
      //
      //Use TestCleanup to run code after each test has run
      //[TestCleanup()]
      //public void MyTestCleanup()
      //{
      //}
      //

      #endregion

      /// <summary>
      ///A test for CodecVersion
      ///</summary>
      [TestMethod()]
      public void SpeexCodecVersionTest()
      {
         Assert.AreEqual<string>("1.0.4", target.CodecVersion);
      }

      /// <summary>
      ///A test for Channels
      ///</summary>
      [TestMethod()]
      public void SpeexChannelsTest()
      {
         Assert.AreEqual<byte>(1, target.Channels);
      }

      /// <summary>
      ///A test for Vendor
      ///</summary>
      [TestMethod()]
      public void SpeexVendorTest()
      {
         Assert.AreEqual<string>("Encoded with Speex speex-1.0.4", target.Vendor);
      }

      /// <summary>
      ///A test for SampleRate
      ///</summary>
      [TestMethod()]
      public void SpeexSampleRateTest()
      {
         Assert.AreEqual<int>(44100, target.SampleRate);
      }

      /// <summary>
      ///A test for Samples
      ///</summary>
      [TestMethod()]
      public void SpeexSamplesTest()
      {
         Assert.AreEqual<long>(61925011, target.Samples);
      }

      /// <summary>
      ///A test for Codec
      ///</summary>
      [TestMethod()]
      public void SpeexCodecTest()
      {
         Assert.AreEqual<OggCodec>(OggCodec.Speex, target.Codec);
      }     

      /// <summary>
      ///A test for SpeexBand
      ///</summary>
      [TestMethod()]
      public void SpeexBandTest()
      {
         Assert.AreEqual<SpeexBand>(SpeexBand.UltraWideband, target.SpeexBand);
      }

      /// <summary>
      ///A test for isSpeexVBR
      ///</summary>
      [TestMethod()]
      public void SpeexVBRTest()
      {
         Assert.AreEqual<bool>(true, target.IsVariableBitrate);
      }

      /// <summary>
      ///A test for TagsCount
      ///</summary>
      [TestMethod()]
      public void SpeexTagsCountTest()
      {
         target.ClearTags();
         target.SaveMetadata();
         target.ReadMetadata(filename);

         target.AddTag("SettedTag2", "My setted value 1");
         target.AddTag("SettedTag2", "My setted value 2");
         target.AddTag("SettedTag2", "My setted value 1");
         target.AddTag("SettedTag", "My setted value");
         target.SaveMetadata();
         target.ReadMetadata(filename);

         Assert.AreEqual<int>(3, target.TagsCount);
      }

      /// <summary>
      ///A test for AddTag
      ///</summary>
      [TestMethod()]
      public void SpeexAddTagTest()
      {
         target.AddTag("NonOfficialTag", "My non official value");
         target.SaveMetadata();
         target.ReadMetadata(filename);

         Assert.AreEqual<string>("My non official value", target["NonOfficialTag"][0]);
      }

      /// <summary>
      ///A test for ClearNonOfficialTag
      ///</summary>
      [TestMethod()]
      public void SpeexClearNonOfficialTagTest()
      {
         target.AddTag("NonOfficialTag", "My non official value");
         target.AddTag("Title", "My title");
         target.Artist = "My artist";
         target.ClearNonOfficialTags();
         target.SaveMetadata();
         target.ReadMetadata(filename);

         Assert.AreEqual<object>(null, target["NonOfficialTag"]);
         Assert.AreEqual<string>("My artist", target.Artist);
         Assert.AreEqual<string>("My title", target.Title);
      }

      /// <summary>
      ///A test for RemoveTag
      ///</summary>
      [TestMethod()]
      public void SpeexRemoveTagTest1()
      {
         target.AddTag("RemovedTag", "My removed value");
         target.SaveMetadata();
         target.ReadMetadata(filename);

         bool actual = target.RemoveTag("RemovedTag");
         Assert.AreEqual<bool>(true, actual);
         actual = target.RemoveTag("NoRemovedTag");
         Assert.AreEqual<bool>(false, actual);
         target.SaveMetadata();
         target.ReadMetadata(filename);

         Assert.AreEqual<object>(null, target["RemovedTag"]);
      }

      /// <summary>
      ///A test for RemoveTag
      ///</summary>
      [TestMethod()]
      public void SpeexRemoveTagTest()
      {
         target.AddTag("RemovedTag", "My removed value 1");
         target.AddTag("RemovedTag", "My removed value 2");
         target.SaveMetadata();
         target.ReadMetadata(filename);

         bool actual = target.RemoveTag("RemovedTag", 1);
         Assert.AreEqual<bool>(true, actual);
         actual = target.RemoveTag("RemovedTag", 2);
         Assert.AreEqual<bool>(false, actual);
         target.SaveMetadata();
         target.ReadMetadata(filename);

         Assert.AreEqual<string>("My removed value 1", target["RemovedTag"][0]);
         Assert.AreEqual<int>(1, target["RemovedTag"].Count);
      }

      /// <summary>
      ///A test for SetTag
      ///</summary>
      [TestMethod()]
      public void SpeexSetTagTest1()
      {
         target.AddTag("SettedTag", "My setted value");
         target.SaveMetadata();
         target.ReadMetadata(filename);

         bool actual = target.SetTag("SettedTag", "My setted value ++");
         Assert.AreEqual<bool>(true, actual);
         actual = target.SetTag("NoSettedTag", "My setted value ++");
         Assert.AreEqual<bool>(false, actual);
         target.SaveMetadata();
         target.ReadMetadata(filename);

         Assert.AreEqual<string>("My setted value ++", target["SettedTag"][0]);
      }

      /// <summary>
      ///A test for SetTag
      ///</summary>
      [TestMethod()]
      public void SpeexSetTagTest()
      {
         target.AddTag("SettedTag2", "My setted value 1");
         target.AddTag("SettedTag2", "My setted value 2");
         target.SaveMetadata();
         target.ReadMetadata(filename);

         bool actual = target.SetTag("SettedTag2", "My setted value 3", 1);
         Assert.AreEqual<bool>(true, actual);
         actual = target.SetTag("SettedTag2", "My setted value 4", 2);
         Assert.AreEqual<bool>(false, actual);
         target.SaveMetadata();
         target.ReadMetadata(filename);

         Assert.AreEqual<string>("My setted value 3", target["SettedTag2"][1]);
         Assert.AreEqual<string>("My setted value 1", target["SettedTag2"][0]);
      }

      /// <summary>
      ///A test for all standard tags
      ///</summary>
      [TestMethod()]
      public void SpeexStandardTagsTest()
      {
         target.Album = "My album";
         target.Artist = "My artist";
         target.Contact = "My contact";
         target.Copyright = "My copyright";
         target.Date = "My date";
         target.Description = "My description";
         target.Genre = "My genre";
         target.ISRC = "My ISRC";
         target.License = "My license";
         target.Location = "My location";
         target.Organization = "My organization";
         target.Performer = "My performer";
         target.Title = "My title";
         target.TrackNumber = "My track number";
         target.Version = "My version";
         target.SaveMetadata();
         target.ReadMetadata(filename);

         Assert.AreEqual<string>("My album", target.Album);
         Assert.AreEqual<string>("My artist", target.Artist);
         Assert.AreEqual<string>("My contact", target.Contact);
         Assert.AreEqual<string>("My copyright", target.Copyright);
         Assert.AreEqual<string>("My date", target.Date);
         Assert.AreEqual<string>("My description", target.Description);
         Assert.AreEqual<string>("My genre", target.Genre);
         Assert.AreEqual<string>("My ISRC", target.ISRC);
         Assert.AreEqual<string>("My license", target.License);
         Assert.AreEqual<string>("My location", target.Location);
         Assert.AreEqual<string>("My organization", target.Organization);
         Assert.AreEqual<string>("My performer", target.Performer);
         Assert.AreEqual<string>("My title", target.Title);
         Assert.AreEqual<string>("My track number", target.TrackNumber);
         Assert.AreEqual<string>("My version", target.Version);
      }

      [TestMethod()]
      public void SpeexLongTagsTest()
      {
         target.AddTag("LongString", TestMaterials.LongString);
         target.SaveMetadata();
         target.ReadMetadata(filename);

         Assert.AreEqual<string>(TestMaterials.LongString, target["LongString"][0]);
      }

      [TestMethod()]
      public void SpeexVeryLongTagsTest()
      {
         target.AddTag("VeryLongString", TestMaterials.VeryLongString);
         target.SaveMetadata();
         target.ReadMetadata(filename);

         Assert.AreEqual<string>(TestMaterials.VeryLongString, target["VeryLongString"][0]);
      }
   }
}